import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn, UpdateDateColumn, OneToMany } from 'typeorm';
import { CreateGroupRequest, UpdateGroupRequest } from '../types/group';
import { Website } from './Website';
import { AppDataSource } from '../config/database';

@Entity('groups')
export class Group {
  @PrimaryGeneratedColumn('uuid')
  id!: string;

  @Column({ type: 'varchar', length: 100 })
  name!: string;

  @Column({ type: 'text', nullable: true })
  description?: string;

  @Column({ type: 'varchar', length: 10, nullable: true })
  icon?: string;

  @Column({ type: 'varchar', length: 7, nullable: true })
  color?: string;

  @Column({ type: 'int', default: 0 })
  order!: number;

  @CreateDateColumn()
  createdAt!: Date;

  @UpdateDateColumn()
  updatedAt!: Date;

  @OneToMany(() => Website, website => website.group)
  websites!: Website[];
}

export class GroupModel {
  private static getRepository() {
    return AppDataSource.getRepository(Group);
  }

  // 获取所有分组
  static async findAll(): Promise<Group[]> {
    const repository = this.getRepository();
    return await repository.find({
      order: { order: 'ASC' },
      relations: ['websites']
    });
  }

  // 根据ID获取分组
  static async findById(id: string): Promise<Group | null> {
    const repository = this.getRepository();
    return await repository.findOne({
      where: { id },
      relations: ['websites']
    });
  }

  // 创建分组
  static async create(data: CreateGroupRequest): Promise<Group> {
    const repository = this.getRepository();
    
    // 如果没有指定order，设置为最大order + 1
    if (!data.order) {
      const maxOrder = await repository.maximum('order') || 0;
      data.order = maxOrder + 1;
    }
    
    const group = repository.create(data);
    return await repository.save(group);
  }

  // 更新分组
  static async update(id: string, data: UpdateGroupRequest): Promise<Group | null> {
    const repository = this.getRepository();
    
    await repository.update(id, data);
    return await this.findById(id);
  }

  // 删除分组
  static async delete(id: string): Promise<boolean> {
    const repository = this.getRepository();
    
    const result = await repository.delete(id);
    return (result.affected || 0) > 0;
  }

  // 检查分组名称是否已存在
  static async existsByName(name: string, excludeId?: string): Promise<boolean> {
    const repository = this.getRepository();
    
    const query = repository.createQueryBuilder('group')
      .where('group.name = :name', { name });
    
    if (excludeId) {
      query.andWhere('group.id != :excludeId', { excludeId });
    }
    
    const count = await query.getCount();
    return count > 0;
  }

  // 获取分组数量
  static async count(): Promise<number> {
    const repository = this.getRepository();
    return await repository.count();
  }

  // 重新排序分组
  static async reorder(groupOrders: { id: string; order: number }[]): Promise<void> {
    const repository = this.getRepository();
    
    for (const { id, order } of groupOrders) {
      await repository.update(id, { order });
    }
  }
}